import { getElementTop } from '@/utils'
import type { Directive, DirectiveBinding } from 'vue'

interface MyHTMLElement extends HTMLElement {
  resizeListener: EventListener
}

export const autoHeight: Directive = {
  mounted(el: MyHTMLElement, binding: DirectiveBinding) {
    // 挂载完成后加入resize事件
    el.resizeListener = () => {
      setHeight(el, binding)
    }

    setHeight(el, binding)

    window.addEventListener('resize', el.resizeListener)
  },

  updated(el: MyHTMLElement, binding: DirectiveBinding) {
    setHeight(el, binding)
  },

  unmounted(el: MyHTMLElement) {
    // 在卸载后销毁resize事件
    window.removeEventListener('resize', el.resizeListener)
  }
}

function setHeight(el: MyHTMLElement, binding: DirectiveBinding) {
  /**
   * 扩展知识点：这里没有直接使用 el.offsetTop
   * offsetTop 是当前元素距离父元素顶部的距离，不是距离body顶部的距离；要获取距离body顶部的距离，需要使用offsetTop加上父元素的offsetTop，直到父元素为body
   */
  const top = getElementTop(el) // el-table 距离窗口顶部偏移量
  const bottom = binding?.value?.bottom || 82 // 底部预留的高度 bottom，默认 82
  const pageHeight = window.innerHeight // 窗口高度

  el.style.height = `${pageHeight - top - bottom}px`
  el.style.overflowY = 'auto' // 让其他 DIV 元素也可以自适应高度滚动
}
